﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Xml;
using Microsoft.Win32;

namespace VIPALABVoiceApp
{
    public delegate void formButtonPressed(string buttonName);
    public delegate void taskEnd();

    public partial class LocalizationServiceForm : Form
    {
        public event formButtonPressed onButtonPressed;
        public event taskEnd taskFinished;

        ScriptInterface si;

        string APIKey = "AIzaSyCG2oZZLh8haVVmqyuIyq0zppkNRHug-xg";
        string mapsURL = "http://www.angiemarin.com/google_maps.html";
        //string mapsURL = Directory.GetCurrentDirectory() + "\\assets\\html\\google_maps.html";
        public string currentLocationX;
        public string currentLocationY;
        bool usingSensor = true;
        WebBrowser places = new WebBrowser();
        bool drawingLine = false;
        bool throwingPin = false;
        bool findingPlaces = false;

        Timer GPSTimer = new Timer();

        AxShockwaveFlashObjects.AxShockwaveFlash placesSWF = new AxShockwaveFlashObjects.AxShockwaveFlash();

        results[] placesResult;

        public LocalizationServiceForm()
        {
            InitializeComponent();

            //Shown += new EventHandler(LocalizationServiceForm_Shown);
            VisibleChanged += new EventHandler(LocalizationServiceForm_VisibleChanged);

            GPSTimer.Interval = 300;
            GPSTimer.Tick += new EventHandler(GPSTimer_Tick);
          
        }

        void placesSWF_FSCommand(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent e)
        {
            switch (e.command)
            {
                case "choosePlace":
                    lookForPlace(e.args);
                    break;
            }
        }

        void lookForPlace(string placeId)
        {
            foreach (var r in placesResult)
            {
                if (r.id == placeId)
                {
                    MyInvokeScript("clearOverlays");
                    MyInvokeScript("addMarker", r.geometry.location.lat, r.geometry.location.lng);
                }
            }
        }

        void showPlacesSWF()
        {
            Form1.InvokeFlashFunction(placesSWF, "clearDictionary", null);
            Form1.InvokeFlashFunction(placesSWF, "clearPlaces", null);
            int indexAux = 0;

            foreach (results r in placesResult)
            {
                Dictionary<string, string> placesDictionary = new Dictionary<string, string>();
                if(!placesDictionary.ContainsKey(r.id))
                    placesDictionary.Add(r.id, "string");
                if (!placesDictionary.ContainsKey(r.name))
                    placesDictionary.Add(r.name, "string");
                else
                    placesDictionary.Add(r.name + " " + indexAux.ToString(), "string");

                Form1.InvokeFlashFunction(placesSWF, "addPlaceName", placesDictionary);
            }

            Form1.InvokeFlashFunction(placesSWF, "showAllPlaces", null);
            
            placesSWF.Visible = true;

            if (taskFinished != null)
                taskFinished();

            placesSWF.Width = (int)(Width * 0.2f);
            placesSWF.Height = (int)(Height * 0.8f);
            placesSWF.Location = new Point(Width - placesSWF.Width, (int)(Height * 0.1f));
            placesSWF.BringToFront();
            placesSWF.Visible = true;
        }

        void hidePlacesSWF()
        {
            placesSWF.Visible = false;
        }

        void GPSTimer_Tick(object sender, EventArgs e)
        {
            MyInvokeScript("setRobocabPosition", currentLocationX, currentLocationY);
        }

        void LocalizationServiceForm_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                initMapsAPI();

                if(Form1.use_gps_sensor)
                    GPSTimer.Start();

                //centerOnRobocab();
            }
            else
            {
                GPSTimer.Stop();
            }
        }

        void LocalizationServiceForm_Shown(object sender, EventArgs e)
        {
            initMapsAPI();
            //centerOnRobocab();
        }

        void initMapsAPI()
        {
            webBrowserMaps.Refresh();
            Version browserInfo = webBrowserMaps.Version;
            webBrowserMaps.Navigated += new WebBrowserNavigatedEventHandler(webBrowserMaps_Navigated);
            webBrowserMaps.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowserMaps_DocumentCompleted);
            //currentLocationX = "37.568889";
            //currentLocationY = "126.976667";
            cacheCleaner.WebBrowserHelper.ClearCache();
            UseIE9DocMode();
            places.Visible = false;
        }

        void places_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            taskEnd placesRequest = new taskEnd(processPlacesRequest);
            places.Invoke(placesRequest);

            taskEnd dispatchSWF = new taskEnd(showPlacesSWF);
            Invoke(dispatchSWF);
        }

        void processPlacesRequest()
        {
            
            string json = places.DocumentText;

            try
            {
                var values = JsonConvert.DeserializeObject<GooglePlacesInfo>(json);
                placesResult = values.results;

                foreach (results r in values.results)
                {
                    MyInvokeScript("addMarker", r.geometry.location.lat, r.geometry.location.lng);
                }
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        void si_reportScriptInvoked(string name, object result)
        {
            MessageBox.Show(result.ToString());
        }
       
        void webBrowserMaps_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            
        }

        void webBrowserMaps_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            //string location = MyInvokeScript("alert('Heloe!');").ToString();
            //MessageBox.Show(location);
        }

        private void LocalizationServiceForm_Load(object sender, EventArgs e)
        {
            si = new ScriptInterface(this);
            webBrowserMaps.ObjectForScripting = si;
            si.reportScriptInvoked += new ScriptInterface.reportScriptResult(si_reportScriptInvoked);
            webBrowserMaps.Navigate(mapsURL);

            Controls.Add(placesSWF);
            placesSWF.LoadMovie(0, Directory.GetCurrentDirectory() + "\\assets\\swf\\places_info.swf");
            placesSWF.Visible = false;
            placesSWF.FSCommand += new AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEventHandler(placesSWF_FSCommand);
        }

        private string MyInvokeScript(string name, params object[] args)
        {
            try
            {
                return webBrowserMaps.Document.InvokeScript(name, args).ToString();
            }
            catch(Exception e)
            {
            }

            return "nada";
        }

        public void searchPlaces(string type)
        {
            getCurrentVehiclePosition();

            string args = "latX=" + currentLocationX + "&latXlatY=" + currentLocationY + "&latYtype=" + type + "&type";
            places = new WebBrowser();
            places.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(places_DocumentCompleted);
            string url = "http://www.angiemarin.com/placesAPI.html#" + args;
            places.Navigate(url, false);
        }

        void getCurrentVehiclePosition()
        {
            string[] centers = MyInvokeScript("getCurrentLocation").Split(',');
            currentLocationX = centers[0].Split('(')[1].Replace(" ", string.Empty);
            currentLocationY = centers[1].Split(')')[0].Replace(" ", string.Empty);

            if (currentLocationX.Length > 9)
                currentLocationX = currentLocationX.Remove(9);
            if (currentLocationY.Length > 9)
                currentLocationY = currentLocationY.Remove(9);
        }

        public void centerOnRobocab()
        {
            string vehicle = MyInvokeScript("getVehiclePosition").Remove(0, 1);
            vehicle = vehicle.Remove(vehicle.Length - 1, 1);
            string[] currentVehicle = vehicle.Split(',');
            MyInvokeScript("changeLocation", currentVehicle[0], currentVehicle[1]);
        }

        private void button1_Click(object sender, EventArgs e)
        {            
            //searchPlaces("food");
            getCurrentVehiclePosition();
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        public void zoomIn()
        {
            MyInvokeScript("ZoomIn");
        }

        public void zoomOut()
        {
            MyInvokeScript("ZoomOut");
        }

        public void panHorizontal(int value)
        {
            MyInvokeScript("panBy", value, 0);
        }

        public void panVertical(int value)
        {
            MyInvokeScript("panBy", 0, value);
        }

        public void clearPlaces()
        {
            MyInvokeScript("clearOverlays");
            MyInvokeScript("deleteOverlays");
        }

        static private void UseIE9DocMode()
        {
            RegistryKey key = null;
            try
            {
                key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", true);
            }
            catch (Exception)
            {
                key = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION");
            }
            key.SetValue(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName, 9999, RegistryValueKind.DWord);
            key.Close();
        }

        public void drawlineBtn_Click(object sender, EventArgs e)
        {
            if (drawLineLabel.BackColor == Color.Red)
            {
                drawLineLabel.BackColor = Color.LimeGreen;

                string destination = MyInvokeScript("getDestination").Remove(0, 1);
                destination = destination.Remove(destination.Length - 1, 1).Replace(" ", string.Empty);
                string[] destinationXY = destination.Split(',');
               
                string current = MyInvokeScript("getVehiclePosition").Remove(0, 1);
                current = current.Remove(current.Length - 1, 1).Replace(" ", string.Empty);
                string[] currentXY = current.Split(',');

                if (destination != "null" && destinationXY.Length > 1)
                    MyInvokeScript("drawLineBetween", destinationXY[0], destinationXY[1], currentXY[0], currentXY[1]);

                drawingLine = true;

                button3.Enabled = true;
            }
            else
            {
                drawLineLabel.BackColor = Color.Red;

                MyInvokeScript("clearLines");

                drawingLine = false;
            }
        }

        public void throwpinBtn_Click(object sender, EventArgs e)
        {
            if (throwpinLabel.BackColor == Color.Red)
            {
                throwpinLabel.BackColor = Color.LimeGreen;

                MyInvokeScript("enableTouchMarker", true);

                throwingPin = true;
            }
            else
            {
                throwpinLabel.BackColor = Color.Red;

                MyInvokeScript("eraseDestination");

                MyInvokeScript("enableTouchMarker", false);

                throwingPin = false;
            }
        }

        public void button3_Click(object sender, EventArgs e)
        {
            MyInvokeScript("eraseDestination");

            MyInvokeScript("deleteOverlays");

            MyInvokeScript("clearLines");

            if(throwingPin)
                throwpinBtn_Click(null, null);

            if(drawingLine)
                drawlineBtn_Click(null, null);

            if (findingPlaces)
                findBtn_Click(null, null);
        }

        public void findBtn_Click(object sender, EventArgs e)
        {
            if (findLabel.BackColor == Color.Red)
            {
                findLabel.BackColor = Color.LimeGreen;

                findingPlaces = true;

                if (onButtonPressed != null)
                    onButtonPressed(findBtn.Name);
            }
            else
            {
                findLabel.BackColor = Color.Red;

                findingPlaces = false;

                if (placesSWF.Visible)
                {
                    MyInvokeScript("showOverlays");
                    placesSWF.Visible = false;
                }

                if (taskFinished != null)
                    taskFinished();
            }
        }
    }

    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public class ScriptInterface
    {
        public delegate void reportScriptResult(string name, object result);

        public event reportScriptResult reportScriptInvoked;
        Form form;

        public ScriptInterface(Form f)
        {
            form = f;
        }

        [System.Web.Services.WebMethod]
        public void callMe(string name, object info)
        {
            if (reportScriptInvoked != null)
                reportScriptInvoked(name, info);
        }
    }
    
}
